import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Settings
{
    private final long FileTypeMagicNumber = 0x0F62B73E988A0253L; // just typed this randomly
    private final int FileTypeVersion = 2; // increase if changing file format

    private final static String SettingsFilePath = "./NCIDE.settings";

    private static String WorkingDirectory;

    public Settings()
    {
        LoadDefaultSettings();

        if ((new File(SettingsFilePath)).exists())
        {
            LoadSettingsFile();
        }
    }

    public static String GetWorkingDirectory()
    {
        if (WorkingDirectory != null)
            return WorkingDirectory;
        else
            return "";
    }

    private void LoadDefaultSettings()
    {
        try
        {
            // https://stackoverflow.com/questions/4032957/how-to-get-the-real-path-of-java-application-at-runtime

            File pto = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI());

            String ProgramPath = pto.getAbsolutePath();

            int LastSlashPos = ProgramPath.lastIndexOf("/");
            if (LastSlashPos < 0)
                LastSlashPos = ProgramPath.lastIndexOf("\\");
            if (LastSlashPos < 0)
                LastSlashPos = -1;

            String ProgramDirectory = ProgramPath.substring(0, LastSlashPos + 1); // notice Java's substring() takes endINDEX, not the length as 2nd parameter!

            WorkingDirectory = ProgramDirectory;
        }
        catch (Exception e)
        {
            System.out.println("error in Settings.LoadDefaultSettings(): " + e.getMessage());
        }
    }

    public String LoadSettingsFile()
    { // returns "" if successful, else error description

        try (DataInputStream is = new DataInputStream(new BufferedInputStream(new FileInputStream(SettingsFilePath)))) // https://jenkov.com/tutorials/java-exception-handling/try-with-resources.html
        {
            // verify
            long FileTypeMagicNumberRead = is.readLong();
            if (FileTypeMagicNumberRead != FileTypeMagicNumber)
            {
                is.close();
                return "File seems not to have been saved by NCIDE";
            }

            int FileTypeVersionRead = is.readInt();
            if (FileTypeVersionRead != FileTypeVersion)
            {
                is.close();
                return "File version does not match this program's version";
            }

            WorkingDirectory = Tools.ReadUTF32Bit(is);

            is.close();

            return "";
        }
        catch (Exception e)
        {
            System.out.println("error in Settings.LoadSettingsFile(): " + e.getMessage());

            String ExceptionMessage = e.getMessage();
            if (ExceptionMessage != null)
                return ExceptionMessage;
            else
                return "[unknown error]";
        }
    }

    public String SaveSettingsFile()
    { // returns "" if successful, else error description

        try (DataOutputStream os = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(SettingsFilePath)))) // https://jenkov.com/tutorials/java-exception-handling/try-with-resources.html
        {
            os.writeLong(FileTypeMagicNumber);
            os.writeInt(FileTypeVersion);

            Tools.WriteUTF32Bit(os, WorkingDirectory);

            os.close();

            return "";
        }
        catch (Exception e)
        {
            System.out.println("error in Settings.SaveSettingsFile(): " + e.getMessage());

            String ExceptionMessage = e.getMessage();
            if (ExceptionMessage != null)
                return ExceptionMessage;
            else
                return "[unknown error]";
        }
    }

    public void SetWorkingDirectory(String WorkingDirectoryNew)
    {
        if (WorkingDirectoryNew == null)
        {
            System.out.println("error in Settings.SetWorkingDirectory(): passed value not useful!");
            return;
        }

        if (WorkingDirectoryNew.length() >= 1 && !(WorkingDirectoryNew.endsWith("//")) && !(WorkingDirectoryNew.endsWith("\\")))
            WorkingDirectoryNew = WorkingDirectoryNew + "/";

        if ((new File(WorkingDirectoryNew)).exists())
            WorkingDirectory = WorkingDirectoryNew;
        else
        {
            WorkingDirectory = "";
            System.out.println("error in Settings.SetWorkingDirectory(): passed value not useful!");
        }
        return;
    }
}
